import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Map;
import java.util.Scanner;

import org.mozilla.javascript.Parser;
import org.mozilla.javascript.ast.AstRoot;

/*
 * "Exception in thread "main" java.util.MissingResourceException: 
 * Can't find bundle for base name org.mozilla.javascript.resources.Messages, 
 * locale en_US" means one of the JavaScript files had a "let", "with", "yield"
 * statement.
 */
public class Main 
{	
	/**
	 * 
	 * @param features
	 * @param file
	 * @throws IOException
	 */
	private static void logLevelFeatures(Map<String, ArrayList<String>> features, File file) throws IOException
	{
		PrintWriter outFile = new PrintWriter(new FileWriter(file));
		
		for(Map.Entry<String, ArrayList<String>> entry : features.entrySet())
		{
			outFile.println(entry.getKey());
			for(String text : entry.getValue())
				outFile.println("\t" + text);
			
			outFile.println();
		}
		
		outFile.close();
	}
	
	public static void main(String[] args)  
	{		
		File extractionDir = new File("ExtractionLogs");
		try
		{
		    if(!extractionDir.exists())
		    	extractionDir.mkdirs();
		}
		catch(Exception e)
		{
			System.err.println("Could not create \"ExtractionLogs\" directory");
		}
		
		File flat = new File("ExtractionLogs/Flat-Level.log");
		File oneLevel = new File("ExtractionLogs/One-Level.log");
		File nLevel = new File("ExtractionLogs/N-Level.log");
		
		
		
		File jsFileDirPath;
		
		if(args.length == 0)
		{
			System.err.println("Please provide a directory for the JavaScript files");
			return;
		}
		
		if(args.length > 1)
		{
			System.err.println("Usage is as follows: \"java Main <directory>\"");
			return;
		}
		
		jsFileDirPath = new File(args[0]);
		
		if(!jsFileDirPath.isDirectory())
		{
			System.err.println(args[0] + " is not a directory");
			return;
		}
		
		try 
		{
			for (File file : jsFileDirPath.listFiles()) 
			{
				Reader reader = new FileReader(file);
				AstRoot root = new Parser().parse(reader, file.getCanonicalPath(), 1);
				reader.close();
				
				FeatureExtractor fe = new FeatureExtractor();
				root.visit(fe);
				
				PrintWriter outFile = new PrintWriter(new FileWriter(flat));
				for(String feature : fe.getFlatLevelFeatures())
					outFile.println(feature);
				outFile.close();
							
				logLevelFeatures(fe.getOneLevelFeatures(), oneLevel);
				logLevelFeatures(fe.getNLevelFeatures(), nLevel);				
			}
			
			Scanner inFile = new Scanner(new File("ExtractionLogs/TestPatternMatching.log"));
            ArrayList<String> sampleTexts = new ArrayList<String>();

            while(inFile.hasNextLine())
            	sampleTexts.add(inFile.nextLine());

            StateTree tree = new StateTree(sampleTexts);                   
            System.out.println(tree);
            System.out.println("Is \"appert\" present in tree: ");
            System.out.println(tree.isFeaturePresent("appert"));
            System.out.println("Is \"alert\" present in tree: ");
            System.out.println(tree.isFeaturePresent("alert"));
            System.out.println("Is \"insert\" present in tree: ");
            System.out.println(tree.isFeaturePresent("insert"));
            System.out.println("Is \"append\" present in tree: ");
            System.out.println(tree.isFeaturePresent("append"));
		}
		catch(IOException e)
		{
			System.err.println("File IO Error");
			e.printStackTrace();
		}
		catch(Exception e)
		{
			System.err.println("Error Parsing the AST");
			e.printStackTrace();
		}		
	}
}